package com.api.user.service.impl;

import com.api.common.JSONUtils;
import com.api.core.response.Result;
import com.api.core.response.ResultGenerator;
import com.api.core.service.AbstractService;
import com.api.user.dao.GameMapper;
import com.api.user.enums.GameEnum;
import com.api.user.model.Game;
import com.api.user.service.GameService;
import com.api.user.vo.GameVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Created by wanghuiwen on 2021/03/18.
 */
@Service
@Transactional
public class GameServiceImpl extends AbstractService<Game> implements GameService {
    @Resource
    private GameMapper gameMapper;

    @Override
    public Result list(String search, String order, Integer page, Integer size){
        Map<String, Object> params = JSONUtils.json2map(search);
        Map<String, Object> orderParams = JSONUtils.json2map(order);
        for (String key : orderParams.keySet()) {
                if (orderParams.get(key) != null && orderParams.get(key).equals("ascending")) orderParams.put(key, "asc");
                if (orderParams.get(key) != null && orderParams.get(key).equals("descending")) orderParams.put(key, "desc");
            }
        PageHelper.startPage(page, size);
        List<Map<String, Object>> res = gameMapper.list(params, orderParams);
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(res);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @Override
    public Result add(Game game) {
        if(game.getGameId() == null){
            game.setDel(false);
            this.save(game);
        }else{
            this.update(game);
        }
        return ResultGenerator.genSuccessResult();
    }

    @Override
    @CacheEvict(value = CACHE_GAME_ENUM_BY_ID, key = "#gameId")
    public Result deleteGame(Long gameId) {
        Game game = this.findById(gameId);
        game.setDel(true);
        this.update(game);
        return ResultGenerator.genSuccessResult();
    }

    @Override
    public Map<Long, GameVo> getIdVoMap(Collection<Long> gameIds) {
        if (CollectionUtils.isEmpty(gameIds)) {
            return Collections.emptyMap();
        }
        String gameIdStr = Joiner.on(",").join(gameIds);
        List<Game> games = gameMapper.selectByIds(gameIdStr);
        ImmutableList<GameVo> gameVos = FluentIterable.from(games)
                .transform(new Function<Game, GameVo>() {
                    @Override
                    public GameVo apply(Game input) {
                        GameVo gameVo = new GameVo();
                        gameVo.setId(input.getGameId());
                        gameVo.setName(input.getGameName());
                        gameVo.setLogo(input.getGameLogo());
                        return gameVo;
                    }
                }).toList();
        return Maps.uniqueIndex(gameVos, new Function<GameVo, Long>() {
            @Override
            public Long apply(GameVo input) {
                return input.getId();
            }
        });
    }

    private static final String CACHE_GAME_ENUM_BY_ID = "game:enum_by_id";
    @Override
    @Cacheable(value = CACHE_GAME_ENUM_BY_ID, key = "#gameId")
    public GameEnum getGameEnumById(Long gameId) {
        Game game = gameMapper.selectByPrimaryKey(gameId);
        return GameEnum.valueOfGameName(game.getGameName());
    }
}
